package com.qiaoba.file.tencent.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.model.*;
import com.qiaoba.api.file.core.FileCore;
import com.qiaoba.api.file.entity.vo.FileUploadVO;
import com.qiaoba.api.file.util.FileUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.Date;
import java.util.UUID;

/**
 * 腾讯云 文件服务实现
 *
 * @author ailanyin
 * @date 2023-09-26 14:36:52
 */
@Service
@RequiredArgsConstructor
public class TencentFileServiceImpl implements FileCore {

    @Value("${tencent.oss.region}")
    private String region;
    @Value("${tencent.oss.appId}")
    private String appId;

    private final COSClient cosClient;

    private static final String URL_TEMPLATE = "https://{}.cos.{}.myqcloud.com/{}";

    @Override
    public FileUploadVO upload(String bucketName, String filename, Long size, InputStream inputStream) {
        try {
            bucketName = handleBucketName(bucketName);
            createBucket(bucketName);
            // 设置存储对象名称
            String objectName = DateUtil.format(new Date(), "yyyy/MM/dd") + "/" + UUID.randomUUID().toString() + "." + FileUtil.getExtension(filename);
            // 创建COS对象的元数据
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(size);
            // 浏览器直接下载
            objectMetadata.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            // 创建上传请求
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream, objectMetadata);
            // 执行上传
            PutObjectResult res = cosClient.putObject(putObjectRequest);

            FileUploadVO vo = new FileUploadVO();
            // https://qiaoba-1308337522.cos.ap-nanjing.myqcloud.com/2023/09/27/a0e0f301-5c50-41cf-ad3a-debb5152040b.jpg
            // https:// + 存储桶 + .cos. + 地区 + .myqcloud.com/ + 文件全路径名
            vo.setUrl(StrUtil.format(URL_TEMPLATE, bucketName, region, objectName));
            vo.setFileName(filename);
            vo.setPath(objectName);
            return vo;
        } finally {
            IoUtil.close(inputStream);
        }
    }

    @Override
    public void delete(String bucketName, String path) {
        bucketName = handleBucketName(bucketName);
        DeleteObjectRequest deleteObjectRequest = new DeleteObjectRequest(bucketName, path);
        cosClient.deleteObject(deleteObjectRequest);
    }

    private String handleBucketName(String oldBucketName) {
        // 用户传进来的原本就是拼接好的桶, 无需处理
        if (oldBucketName.endsWith(appId)) {
            return oldBucketName;
        }

        return oldBucketName + "-" + appId;
    }

    private void createBucket(String bucketName) {
        // 处理桶名称, 腾讯云OSS桶名称需要加上APPID,比如 pic-10010 10010就是APPID

        boolean exists = cosClient.doesBucketExist(bucketName);
        if (exists) {
            return;
        }
        // 创建存储桶
        CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
        cosClient.createBucket(createBucketRequest);
        // 设置存储桶的ACL，使其对所有人可读
        SetBucketAclRequest setBucketAclRequest = new SetBucketAclRequest(bucketName, CannedAccessControlList.PublicRead);
        cosClient.setBucketAcl(setBucketAclRequest);
        // 启用存储桶版本控制
        SetBucketVersioningConfigurationRequest versioningRequest = new SetBucketVersioningConfigurationRequest(bucketName, new BucketVersioningConfiguration(BucketVersioningConfiguration.ENABLED));
        cosClient.setBucketVersioningConfiguration(versioningRequest);
    }

}
